import { ArrayMethods } from './arr'
export function observer(data) {
  //  判断data是不是对象 不是对象直接返回 是对象遍历
  if (typeof data !== 'object' && typeof data !== null) return data
  // 返回类
  return new Observer(data)
}
class Observer {
  constructor(data) {
    // 给data定义一个属性
    Object.defineProperty(data, '__ob__', {
      enumerable: false, // 不能进行枚举
      value: this,
    })
    // 判断数据是数组还是对象
    if (Array.isArray(data)) {
      data.__proto__ = ArrayMethods
      // 如果是数组嵌套对象 需要加以处理
      this.observerArray(data)
    } else {
      this.walk(data) // 遍历data 形参data就是外部vue return出来的对象 例{a:1}
    }
  }
  walk(data) {
    let keys = Object.keys(data) //返回一个data所有属性名的数组
    // 遍历这个属性名的数组
    for (let i = 0; i < keys.length; i++) {
      let key = keys[i] // 属性名
      let value = data[key] // 属性值
      // 监听数据
      defineReactive(data, key, value)
    }
  }
  observerArray(value) {
    for (let i = 0; i < value.length; i++) {
      observer(value[i])
    }
  }
}
// 对对象的属性进行劫持
function defineReactive(data, key, value) {
  observer(value) // 深度代理
  Object.defineProperty(data, key, {
    get() {
      return value
    },
    set(newValue) {
      // 判断新数据是否和原始数据相同
      if (newValue === value) return
      observer(newValue) // 设置的值是对象也要进行递归监听
      value = newValue
    },
  })
}
